package com.example.aigc_education.service.impl;

import cn.hutool.core.bean.BeanUtil;
//import com.agentsflex.agent.LLMAgent;
//import com.agentsflex.agent.Output;
//import com.agentsflex.llm.MessageResponse;
import com.agentsflex.llm.spark.SparkLlm;
//import com.agentsflex.message.AiMessage;
//import com.agentsflex.message.HumanMessage;
//import com.agentsflex.message.SystemMessage;
//import com.agentsflex.prompt.HistoriesPrompt;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.domain.Question;
import com.example.aigc_education.domain.dto.AiQuestionDTO;
import com.example.aigc_education.domain.vo.QuestionAnalysisVO;
import com.example.aigc_education.prompt.ProduceQuestionPrompts;
import com.example.aigc_education.service.QuestionService;
import com.example.aigc_education.mapper.QuestionMapper;
import com.example.aigc_education.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author 23918
* @description 针对表【stu_question】的数据库操作Service实现
* @createDate 2024-06-06 14:06:30
*/
@Slf4j
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question>
    implements QuestionService{

    @Resource
    private SparkLlm sparkLlm;

    @Resource
    private QuestionMapper questionMapper;


    @Override
    public boolean generateQuestion(String courseName, String studyCapacity) {
        return false;
    }

//    @Override
//    public int generateQuestionList(String subject,
//                                        String grade,
//                                        String textbook,
//                                        String questionType,
//                                        int questionNum,
//                                        String difficulty,
//                                        String unitName,
//                                        String unitContent,
//                                        String scene) {
//
//        SystemMessage systemMessage = new SystemMessage(ProduceQuestionPrompts.PRODUCE_QUESTION_SYSTEM_PROMPT);
//        HistoriesPrompt historiesPrompt = new HistoriesPrompt();
//        historiesPrompt.addMessage(systemMessage);
//
//        String prompt = "学科：" + grade + subject + "\n" +
//                "教材："+textbook+ "\n" +
//                "单元名称：" + unitName + "\n" +
//                "题型：" + questionType + "\n" +
//                "题量：5道\n" +
//                "难度：" + difficulty + "\n" +
//                "单元目录：\n" + unitContent + "\n";
//        if (scene != null && !StringUtils.isEmpty(scene)) {
//            prompt += "情景：" + scene + "\n";
//        }
//
//        System.out.println(prompt);
//
//        int successNum = 0;
//        String content = " ";
//        for (int i = 0; i < questionNum/5 ; i++) {
//            if (i == 0) {
//                historiesPrompt.addMessage(new HumanMessage(prompt));
//                MessageResponse<AiMessage> res = sparkLlm.chat(historiesPrompt);
////                System.out.println(res.getMessage().getContent());
//                content = res.getMessage().getContent().replace("```json", "").replace("```", "");
////                log.info("content:{}",content);
//
//                JSONArray jsonArray = JSONArray.parseArray(content);
//
//                for (int j = 0; j < jsonArray.size(); j++) {
//                    AiQuestionDTO question = jsonArray.getObject(j, AiQuestionDTO.class);
//                    log.info("question:{}",question);
//                    // AiQuestionDTO to Question
//                    Question actualQuestion = BeanUtil.toBean(question, Question.class);
//                    actualQuestion.setSubject(grade + subject);
//                    int insertRes = questionMapper.insert(actualQuestion);
//                    if (insertRes == 1) {
//                        successNum++;
//                    }
//                }
//
//            } else {
//                prompt = "继续生成5道";
//
//                HumanMessage humanMessage = new HumanMessage(prompt);
//                historiesPrompt.addMessage(humanMessage);
//
//                MessageResponse<AiMessage> chat = sparkLlm.chat(historiesPrompt);
//                historiesPrompt.addMessage(chat.getMessage());
//                content = chat.getMessage().getContent().replace("```json", "").replace("```", "");
////                System.out.println(content);
////                log.info("content:{}",content);
//
//                JSONArray jsonArray = JSONArray.parseArray(content);
//
//                for (int j = 0; j < jsonArray.size(); j++) {
//                    AiQuestionDTO question = jsonArray.getObject(j, AiQuestionDTO.class);
//                    log.info("question:{}",question);
//                    Question actualQuestion = BeanUtil.toBean(question, Question.class);
//                    actualQuestion.setSubject(grade + subject);
//                    int insertRes = questionMapper.insert(actualQuestion);
//                    if (insertRes == 1) {
//                        successNum++;
//                    }
//                }
//            }
//        }
//        return successNum;
//    }

//    @Transactional
//    @Override
//    public int generateQuestionList(String subject,
//                                    String grade,
//                                    String textbook,
//                                    String questionType,
//                                    int questionNum,
//                                    String difficulty,
//                                    String unitName,
//                                    String unitContent,
//                                    String scene) {
//
//        SystemMessage systemMessage = new SystemMessage(ProduceQuestionPrompts.PRODUCE_QUESTION_SYSTEM_PROMPT);
//        HistoriesPrompt historiesPrompt = new HistoriesPrompt();
//        historiesPrompt.addMessage(systemMessage);
//
//        String prompt = generatePrompt(subject, grade, textbook, questionType, difficulty, unitName, unitContent, scene);
//
//        int successNum = 0;
//        for (int i = 0; i < questionNum / 5; i++) {
//            if (i != 0) {
//                prompt = "继续生成5道";
//            }
//            successNum += generateAndSaveQuestions(historiesPrompt, prompt, grade + subject, difficulty);
//        }
//        return successNum;
//    }

    @Transactional
    @Override
    public List<Question> generateQuestionList(String textbook,
                                               String questionType,
                                               int questionNum,
                                               String difficulty,
                                               String unitName,
                                               String unitContent,
                                               String scene) {

//        SystemMessage systemMessage = new SystemMessage(ProduceQuestionPrompts.PRODUCE_QUESTION_SYSTEM_PROMPT);
//        HistoriesPrompt historiesPrompt = new HistoriesPrompt();
//        historiesPrompt.addMessage(systemMessage);

        String prompt = generatePrompt( textbook, questionType, difficulty, unitName, unitContent, scene);

        List<Question> questions = new ArrayList<>();
        for (int i = 0; i < questionNum / 5; i++) {
            if (i != 0) {
                prompt = "继续生成5道";
            }
//            questions.addAll(generateAndSaveQuestions(historiesPrompt, prompt, difficulty));
        }
        return questions;
    }

    private String generatePrompt(  String textbook, String questionType, String difficulty, String unitName, String unitContent, String scene) {
        return "单元名称：" + unitName + "\n" +
                "题型：" + questionType + "\n" +
                "题量：5道\n" +
                "难度：" + difficulty + "\n" +
                "单元目录：\n" + unitContent + "\n" +
                (scene != null && !StringUtils.isEmpty(scene) ? "情景：" + scene + "\n" : "");
    }

//    private int generateAndSaveQuestions(HistoriesPrompt historiesPrompt, String prompt, String subject, String difficulty) {
//        HumanMessage humanMessage = new HumanMessage(prompt);
//        historiesPrompt.addMessage(humanMessage);
//
//        MessageResponse<AiMessage> chat = sparkLlm.chat(historiesPrompt);
//        historiesPrompt.addMessage(chat.getMessage());
//        String content = chat.getMessage().getContent().replace("```json", "").replace("```", "");
//
////        JSONArray jsonArray = JSONArray.parseArray(content);
//        JSONArray jsonArray = null;
//        if (content.trim().startsWith("{")) {
//            JSONObject jsonObject = JSONObject.parseObject(content);
//            jsonArray = new JSONArray();
//            jsonArray.add(jsonObject);
//        }else {
//           jsonArray = JSONArray.parseArray(content);
//        }
//
//        int successNum = 0;
//        for (int j = 0; j < jsonArray.size(); j++) {
//            AiQuestionDTO question = jsonArray.getObject(j, AiQuestionDTO.class);
//            log.info("question:{}", question);
//            Question actualQuestion = BeanUtil.toBean(question, Question.class);
//            actualQuestion.setSubject(subject);
//            actualQuestion.setDifficulty(showQuestionDifficulty(difficulty));
//            try {
//                int insertRes = questionMapper.insert(actualQuestion);
//                if (insertRes == 1) {
//                    successNum++;
//                }
//            } catch (Exception e) {
//                log.error("Error while saving question to database", e);
//            }
//        }
//        return successNum;
//    }

//    private List<Question> generateAndSaveQuestions(HistoriesPrompt historiesPrompt, String prompt, String difficulty) {
//        HumanMessage humanMessage = new HumanMessage(prompt);
//        historiesPrompt.addMessage(humanMessage);
//
//        MessageResponse<AiMessage> chat = sparkLlm.chat(historiesPrompt);
//        historiesPrompt.addMessage(chat.getMessage());
//        String content = chat.getMessage().getContent().replace("```json", "").replace("```", "");
//
//        JSONArray jsonArray = null;
//        try {
//            if (content.trim().startsWith("{")) {
//                JSONObject jsonObject = JSONObject.parseObject(content);
//                jsonArray = new JSONArray();
//                jsonArray.add(jsonObject);
//            }else {
//                jsonArray = JSONArray.parseArray(content);
//            }
//        } catch (JSONException e) {
//            throw new BusinessException("Error while parsing JSON content").setDetailMessage(e.getMessage());
//        }
//
//        List<Question> questions = new ArrayList<>();
//        for (int j = 0; j < jsonArray.size(); j++) {
//            AiQuestionDTO question = jsonArray.getObject(j, AiQuestionDTO.class);
//            log.info("question:{}", question);
//            Question actualQuestion = BeanUtil.toBean(question, Question.class);
//            actualQuestion.setDifficulty(showQuestionDifficulty(difficulty));
//            try {
//                int insertRes = questionMapper.insert(actualQuestion);
//                if (insertRes == 1) {
//                    questions.add(actualQuestion);
//                }
//            } catch (Exception e) {
//                log.error("Error while saving question to database", e);
//                throw new BusinessException("Error while saving question to database");
//            }
//        }
//        return questions;
//    }

    private int showQuestionDifficulty(String difficulty) {
        //题目难度 容易：0， 较易：1， 中等：2， 较难：3， 困难：4
        if ("容易".equals(difficulty)) {
            return 0;
        } else if ("较易".equals(difficulty)) {
            return 1;
        } else if ("中等".equals(difficulty)) {
            return 2;
        } else if ("较难".equals(difficulty)) {
            return 3;
        } else if ("困难".equals(difficulty)) {
            return 4;
        } else {
            return 0;
        }
    }



    /**
     * 根据考试ID查询具体考试题目。
     *
     * 本方法通过调用questionMapper的selectExamQuestionByExamId方法，根据给定的考试ID查询相应的考试题目。
     * 如果查询过程中发生异常，方法将捕获异常并抛出一个运行时异常，提示“查询考试题目失败”。
     * 这样做的目的是为了在更高的层次上处理异常，提供更具体的错误信息，并保持方法的简洁性。
     *
     * @param examId 考试的唯一标识ID，用于查询与该考试相关的题目。
     * @return 返回一个包含考试题目的列表。如果考试ID不存在或查询失败，返回空列表。
     * @throws RuntimeException 如果查询考试题目过程中发生异常，抛出运行时异常。
     */
    @Override
    public List<Question> selectExamQuestionByExamId(Long examId) {
        try {
            // 尝试通过考试ID查询考试题目
            return questionMapper.selectExamQuestionByExamId(examId);
        } catch (Exception e) {
            // 捕获并处理查询过程中可能出现的异常
            throw new RuntimeException("查询考试题目失败");
        }
    }


    @Override
    public QuestionAnalysisVO getQuestionAnalysis(String questionJson) {
//        LLMAgent agent = new LLMAgent(sparkLlm, ProduceQuestionPrompts.PRODUCE_ANALYSIS_SYSTEM_PROMPT);
//        Map<String, Object> variables = new HashMap<>();
//        variables.put("questionDetail", questionJson);
//        String json = null;
//        try {
//            Output output = agent.execute(variables, null);
////        System.out.println(output.getValue());
//            Object value = output.getValue();
//            json = value.toString().replace("```json", "").replace("```", "");
//        } catch (Exception e) {
//            throw new BusinessException("分析错题失败");
//        }
//        return JSONObject.parseObject(json, QuestionAnalysisVO.class);
        return null;
    }

    @Transactional
    public void addQuestion(Question question) {
        try {
            questionMapper.insert(question);
        } catch (Exception e) {
            throw new BusinessException("添加题目失败");
        }
    }

    @Override
    @Transactional
    public void updateQuestion(Question question, Long questionId) {
        try {
            question.setQuestionId(questionId);
            questionMapper.updateById(question);
        } catch (Exception e) {
            throw new BusinessException("更新题目失败");
        }
    }


    @Override
    @Transactional
    public void deleteQuestion(Long questionId) {
        try {
            questionMapper.deleteById(questionId);
        } catch (Exception e) {
            throw new BusinessException("删除题目失败");
        }
    }


    @Override
    public List<Question> selectQuestionList() {
        try {
            return questionMapper.selectList(null);
        } catch (Exception e) {
            throw new BusinessException("查询题目列表失败");
        }
    }
}




